// ============================================================================
// Name : WingEntityClassLoader.java
// Author : iron.yin@gmail.com
// Version : v1.0
// Copyright : RisingSun CO,.LTD
// Description : WingEntityClassLoader.java in Java
// ============================================================================
package cc.risingsun.wing.core.loader;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Set;

import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.util.TraceClassVisitor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cc.risingsun.wing.ds.DataStruct;

/**
 * 
 * @author iron.yin@gmail.com
 */
public class WingEntityClassLoader extends ClassLoader{

	private static final Logger logger = LoggerFactory.getLogger(WingClassLoader.class);

	private Set<String> classes;
	
	final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
	final ClassVisitor cv = new RepositoryReactivator(cw);

	public WingEntityClassLoader() {
		classes = DataStruct.hashSet();
	}

	@Override
	protected synchronized Class<?> loadClass(String name, boolean resolve)
			throws ClassNotFoundException {
		if (classes.contains(name)) {
			String resource = name.replace('.', '/') + ".class";
			InputStream is = getResourceAsStream(resource);
			byte[] bytes = null;
			try {
				ClassReader cr = new ClassReader(is);
				cr.accept(cv, 0);
				bytes = cw.toByteArray();
				cr = new ClassReader(bytes);
				TraceClassVisitor tcv = new TraceClassVisitor(new PrintWriter(System.out));
				cr.accept(tcv, 0);
				File file = new File("C:\\Users\\Administrator\\Desktop\\Bean.class");
				FileOutputStream fout = new FileOutputStream(file);
				fout.write(bytes);
				fout.close();
			} catch (IOException e) {
				logger.error(e.getMessage(), e);
			}
			return defineClass(name, bytes, 0, bytes.length);
		}
		return super.loadClass(name, resolve);
	}
	
	private class RepositoryReactivator extends ClassVisitor implements Opcodes{

		public RepositoryReactivator(ClassVisitor cv) {
			super(ASM4, cv);
		}
		
	}

}
